package com.online.music.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.online.music.entity.dto.PlaylistAddSongsDTO;
import com.online.music.entity.po.Playlist;
import com.online.music.entity.po.Song;
import com.online.music.entity.po.SongPlaylist;
import com.online.music.exception.BaseException;
import com.online.music.mapper.PlaylistMapper;
import com.online.music.mapper.SongMapper;
import com.online.music.service.IPlaylistService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.online.music.service.ISongPlaylistService;
import com.online.music.utils.UserContextUtil;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.online.music.common.Result;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Author: Leno
 * @Date: 2025-01-31
 * @Description: PlaylistServiceImpl
 */
@Service
@RequiredArgsConstructor
public class PlaylistServiceImpl extends ServiceImpl<PlaylistMapper, Playlist> implements IPlaylistService {

    private final PlaylistMapper playlistMapper;

    private final SongMapper songMapper;

    private final ISongPlaylistService songPlaylistService;

    @Override
    public Result<Page<Playlist>> findPage(Integer pageNum, Integer pageSize, Playlist playlist) {
        Page<Playlist> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Playlist> lqw = new LambdaQueryWrapper<>();

        // 1. 获取当前用户ID（从安全上下文或Token中解析）
        Long currentUserId = UserContextUtil.getUserId();

        // 2. 根据传入参数动态添加条件
        if (playlist != null) {
            // 根据歌单名称模糊查询
            lqw.like(StrUtil.isNotBlank(playlist.getName()), Playlist::getName, playlist.getName());
            // 用户自己的歌单
            lqw.eq(playlist.getUserId() != null, Playlist::getUserId, playlist.getUserId());
        }

        // 3. 关键逻辑：可见性控制
        if (playlist != null && playlist.getUserId() != null) {
            // 如果查询的是其他用户的歌单（非自己），则只显示公开歌单
            if (!playlist.getUserId().equals(currentUserId)) {
                lqw.eq(Playlist::getViewStatus, 1); // 只查公开歌单
            }
        } else {
            // 没有指定用户ID时，只能查看公开歌单或自己的歌单
            lqw.and(wq -> wq.eq(Playlist::getViewStatus, 1)
                    .or()
                    .eq(Playlist::getUserId, currentUserId));
        }

        // 4. 执行分页查询
        return Result.success(page(page, lqw));
    }

    @Override
    @Transactional
    public Result<String> deleteBatch(List<Long> ids) {
        // 删除前先判断是否存在...
        removeByIds(ids);
        // 删除歌单与歌曲的关联关系
        songPlaylistService.remove(
                new LambdaQueryWrapper<SongPlaylist>()
                        .in(SongPlaylist::getPlaylistId, ids)
        );
        return Result.successMsg("删除成功");
    }

    @Override
    public Result<String> addSongsToPlayList(PlaylistAddSongsDTO playlistDTO) {
        Set<Long> songIds = playlistDTO.getSongIds();
        Long playlistId = playlistDTO.getId();

        // 1. 校验歌单是否存在且属于当前用户
        Playlist playlist = this.getById(playlistId);
        if (playlist == null || !playlist.getUserId().equals(UserContextUtil.getUserId())) {
            throw new BaseException("歌单不存在或无权操作");
        }
        // 2. 校验歌曲是否存在且状态为“已发布”（status=1）
        List<Song> validSongs = songMapper.selectList(
                new LambdaQueryWrapper<Song>()
                        .in(Song::getId, playlistDTO.getSongIds())
                        .eq(Song::getStatus, 1)
        );
        if (validSongs.size() != songIds.size()) {
            throw new BaseException("存在无效歌曲");
        }

        // 3. 去重并批量插入关联关系
        List<SongPlaylist> relations = songIds.stream()
                .filter(songId -> !isSongInPlaylist(songId, playlistId)) // 去重逻辑
                .map(songId -> new SongPlaylist(songId, playlistId))
                .collect(Collectors.toList());
        songPlaylistService.saveBatch(relations);
        return Result.successMsg("添加歌曲成功");
    }

    @Override
    @Transactional
    public Result<String> removeSongsFromPlayList(PlaylistAddSongsDTO playlistDTO) {
        Set<Long> songIds = playlistDTO.getSongIds();
        Long playlistId = playlistDTO.getId();

        if (songIds != null && !songIds.isEmpty()) {
            songPlaylistService.remove(
                    new LambdaQueryWrapper<SongPlaylist>()
                            .in(SongPlaylist::getSongId, songIds)
                            .eq(SongPlaylist::getPlaylistId, playlistId)
            );
        }
        return Result.successMsg("移除歌曲成功");
    }

    @Override
    public Result<List<Song>> getPlaylistSongs(Long id, String name) {
        List<Song> songs = songMapper.selectPlayListSongs(id, name);
        return Result.success(songs);
    }

    @Override
    public Result<List<Song>> getAvailableSongs(String name) {
        // 返回歌单可用的歌曲信息,全部审核通过的歌曲
        LambdaQueryWrapper<Song> eq = new LambdaQueryWrapper<Song>()
                .eq(Song::getStatus, 1);
        if (StrUtil.isNotBlank(name)) {
            eq.like(Song::getName, name);
        }
        List<Song> songs = songMapper.selectList(
                eq
        );
        return Result.success(songs);
    }

    private boolean isSongInPlaylist(Long songId, Long playlistId) {
        return songPlaylistService.count(
                new LambdaQueryWrapper<SongPlaylist>()
                        .eq(SongPlaylist::getSongId, songId)
                        .eq(SongPlaylist::getPlaylistId, playlistId)
        ) > 0;
    }

}

